package com.demo.practiceui.views.chart;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * 环形图（甜甜圈图）
 * 核心知识点：
 * 1. canvas.drawArc() - 绘制扇形/弧形
 * 2. RectF - 定义绘制区域
 * 3. 角度计算 - 数据占比转换为角度
 * 4. 多层绘制 - 先绘制扇形，再覆盖中心圆形
 */
public class DonutChartView extends View {

    // 数据源
    private float[] data = {30, 25, 20, 15, 10};
    private String[] labels = {"销售", "研发", "市场", "运营", "其他"};
    private int[] colors = {
            Color.parseColor("#FF5722"),
            Color.parseColor("#4CAF50"),
            Color.parseColor("#2196F3"),
            Color.parseColor("#FFC107"),
            Color.parseColor("#9C27B0")
    };

    // 画笔
    private Paint arcPaint;        // 扇形画笔
    private Paint textPaint;       // 文字画笔
    private Paint centerPaint;     // 中心圆画笔

    // 尺寸相关
    private int width;
    private int height;
    private float centerX;
    private float centerY;
    private float radius;          // 外圆半径
    private float innerRadius;     // 内圆半径（形成环形效果）

    private RectF rectF;           // 绘制区域
    private float totalValue;      // 数据总和

    public DonutChartView(Context context) {
        this(context, null);
    }

    public DonutChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DonutChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        // 扇形画笔
        arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        arcPaint.setStyle(Paint.Style.FILL);

        // 文字画笔
        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(Color.parseColor("#333333"));
        textPaint.setTextSize(32f);
        textPaint.setTextAlign(Paint.Align.LEFT);

        // 中心圆画笔
        centerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        centerPaint.setColor(Color.WHITE);
        centerPaint.setStyle(Paint.Style.FILL);

        rectF = new RectF();

        // 计算总值
        calculateTotal();
    }

    private void calculateTotal() {
        totalValue = 0;
        for (float value : data) {
            totalValue += value;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (widthMode == MeasureSpec.AT_MOST) {
            width = 800;
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            height = 600;
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        centerX = width / 2f;
        centerY = height / 2f;

        // 计算半径，留出空间给图例
        radius = Math.min(width, height) / 2f - 100;
        innerRadius = radius * 0.6f;  // 内圆半径是外圆的60%

        // 定义绘制区域
        rectF.set(centerX - radius, centerY - radius, 
                  centerX + radius, centerY + radius);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 1. 绘制扇形（环形的外部）
        drawArcs(canvas);

        // 2. 绘制中心白色圆（形成环形空心效果）
        canvas.drawCircle(centerX, centerY, innerRadius, centerPaint);

        // 3. 绘制中心文字
        drawCenterText(canvas);

        // 4. 绘制图例
        drawLegend(canvas);
    }

    /**
     * 绘制扇形
     */
    private void drawArcs(Canvas canvas) {
        float startAngle = -90f;  // 从顶部（12点方向）开始

        for (int i = 0; i < data.length; i++) {
            // 计算当前扇形的角度
            float sweepAngle = (data[i] / totalValue) * 360f;

            // 设置颜色
            arcPaint.setColor(colors[i]);

            // 绘制扇形
            // 参数：绘制区域, 起始角度, 扫过角度, 是否连接中心点, 画笔
            canvas.drawArc(rectF, startAngle, sweepAngle, true, arcPaint);

            startAngle += sweepAngle;  // 更新下一个扇形的起始角度
        }
    }

    /**
     * 绘制中心文字
     */
    private void drawCenterText(Canvas canvas) {
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(48f);
        textPaint.setColor(Color.parseColor("#333333"));
        
        canvas.drawText("总计", centerX, centerY - 20, textPaint);
        
        textPaint.setTextSize(56f);
        textPaint.setColor(Color.parseColor("#2196F3"));
        canvas.drawText(String.format("%.0f", totalValue), centerX, centerY + 40, textPaint);
    }

    /**
     * 绘制图例
     */
    private void drawLegend(Canvas canvas) {
        float legendX = 40;
        float legendY = height - 200;
        float legendSize = 30;
        float legendSpacing = 60;

        textPaint.setTextSize(32f);
        textPaint.setTextAlign(Paint.Align.LEFT);
        textPaint.setColor(Color.parseColor("#333333"));

        for (int i = 0; i < data.length; i++) {
            // 绘制颜色方块
            arcPaint.setColor(colors[i]);
            canvas.drawRect(legendX, legendY, 
                          legendX + legendSize, legendY + legendSize, arcPaint);

            // 绘制标签和数值
            float percentage = (data[i] / totalValue) * 100;
            String text = labels[i] + ": " + String.format("%.1f%%", percentage);
            canvas.drawText(text, legendX + legendSize + 20, legendY + legendSize - 5, textPaint);

            legendY += legendSpacing;
        }
    }

    /**
     * 设置数据
     */
    public void setData(float[] data, String[] labels, int[] colors) {
        this.data = data;
        this.labels = labels;
        this.colors = colors;
        calculateTotal();
        invalidate();
    }
}

